﻿#pragma once
#include <QWidget>
#include <thread>

#include "device_info.hpp"
#include "json.hpp"
#include "multicast_acceptor.hpp"
#include "multicast_sender.hpp"
#include <QStringListModel>

#include "broadcast_acceptor.hpp"
#include "broadcast_sender.hpp"

QT_BEGIN_NAMESPACE

namespace Ui
{
    class ClientGUI;
}

QT_END_NAMESPACE

class ClientGUI : public QWidget
{
    Q_OBJECT

public:
    explicit ClientGUI(QWidget* parent = nullptr);
    ~ClientGUI() override;

signals:
    void signalLog(QString message);

    void signalDeviceSearch(QString data);

protected:
    void initUI();

    void onClickedCreateConnection();

    void onDataReceived(const std::vector<uint8_t>& data, const std::string& ip, uint16_t port);

    void onClickedRefreshDeviceList();

    bool sendRequest(const std::string& url, const nlohmann::json& data) const;

    void handleLogSignal(const QString& message) const;

    void onClickedLogAreaClear() const;

    void onClickedLogContentExport();

    void onClickedSyncDeviceTime();

    void onClickedSubmitDeviceInfo();

    void onHandleDeviceSearch(const nlohmann::json& body, const std::string& ip, uint16_t port);

    void onHandleDeviceModify(const nlohmann::json& body, const std::string& ip, uint16_t port);

    void onHandleDeviceTimeSet(const nlohmann::json& body, const std::string& ip, uint16_t port);

    static void onHandleDeviceTimeGet(const nlohmann::json& body, const std::string& ip, uint16_t port);

    void onClickedDeviceList(const QModelIndex& index);

    void onLocalTimerTimeout() const;

    void handelSignalDeviceSearch(const QString& data);

private:
    Ui::ClientGUI* ui;

    const std::string client_id;

    std::shared_ptr<MulticastAcceptor> sp_multicast_acceptor;
    std::shared_ptr<MulticastSender> sp_multicast_sender;

    std::shared_ptr<BroadcastAcceptor> sp_broadcast_acceptor;
    std::shared_ptr<BroadcastSender> sp_broadcast_sender;

    std::thread thread_acceptor;

    std::map<std::string, DeviceInfo> map_device_info;
    std::string current_device_serial;
    QStringListModel* model_device_list = nullptr;
};
